#!/usr/bin/env python
# coding=utf-8

import sys
import os
from optparse import *
from coli import *
from env import ISF_LICENSE

    
class BaseExploit(CommandlineWrapper):
    register_info = {
        'ID': '',
        'Name': 'The Exploit Base Framework',
        'Author': 'w3h',
        'License': ISF_LICENSE,
        'Created': '2015-01-08',
        'Description': '',

        'Vendor': '',
        'Device': '',
        'App': '',
        'Protocol': '',
        'References': {
            'CVE': '',
            'OSVDB': '',
            'CNVD': '',
            'CNNVD': ''
        },

        'Risk': '',  # H/M/L
        'VulType': ''
    }

    register_options = []

    def __init__(self):
        CommandlineWrapper.__init__(self)

    def init_user_options(self):
        self.base_options = [
            make_option('--verbose', action='store_true', dest='verbose',
                        default=False, help='Print verbose information.')
        ]

        targetflag = False
        for i in self.register_options:
            if i.get_opt_string()[2:] == 'TargetIp':
                targetflag = True

        if not targetflag:
            newopt = make_option('-t', '--TargetIp', action='store', dest='TargetIp',
                                 type='string', default=None,
                                 help='The target of this poc.')
            self.base_options.insert(0, newopt)

        self.base_options += self.register_options

    def get_options(self):
        self.init_user_options()
        self.get_coli_parser().add_options(self.base_options)

    def getParam(self, para):
        for (k, v) in self.options.__dict__.items():
            if not k == para:
                continue
            for i in self.base_options:
                if k == i.get_opt_string()[2:]:
                    if 'int' == i.type:
                        return int(v)
                    else:
                        return v

        return None

    def __call__(self, argv):
        self.get_options()
        try:
            (opts, args) = self.get_coli_parser().parse_args(argv)
            self.options = opts
            if not argv:
                self.get_coli_parser().print_help()
                return

            if opts.InConfig is None:
                # not xml file run mode
                self.__shellCall(opts, args)
                return

            super(BaseExploit, self).__call__(argv)
        except Exception as e:
            print "[+] Failed: {0}".format(e.__class__.__doc__)
            raise

    def __shellCall(self, opts, args):
        context = {}
        # get user para and global Paramaters
        self.options = opts

        try:
            self.TargetPort = 0
            self.TargetIp = self.getParam('TargetIp')
            self.TargetPort = str(self.getParam('TargetPort'))
        except:
            pass

        (fhNo, logConfig) = self.processWrapperParams(opts)
        retval = self.processParams(opts.__dict__, None, None, context, logConfig)

    #
    # These need to be implemented by the exploit
    # 
    def processParams(self, inputs, constants, outputs, context, logConfig):
        """Process the input parameters and achieve the intended purpose"""
        try:
            # script pre check
            if not self.check():
                return

            return self.exploit(inputs, constants, outputs, context, logConfig)
        except Exception,e:
            raise

    def getID(self):
        """Return the plugin ID"""
        return 0

    def cleanup(self, flags, context, logConfig):
        """Cleanup any errant connections or data after the rendezvous is done"""
        return

    def validateParams(self, inputs):
        """Validate parameters to verify sane values"""
        return True

    def exploit(self, *args, **kwargs):
        """Process the input parameters and achieve the intended purpose"""
        raise NotImplementedError("processParams must be implemented")

    def check(self, *args, **kwargs):
        return True


def MainEntry(obj, flag):
    if flag == "__main__":
        z = obj()
        z(sys.argv[1:])
